package com.upeoe.shiro;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.mgt.SecurityManager;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author ven_hxz
 * @create 2016-07-01 上午10:48
 */
public class Tutorial2 {
    private static final transient Logger logger = LoggerFactory.getLogger(Tutorial2.class);

    public static void main(String[] args) {
        logger.info("Apache Shiro Tutorial about SecurityManager Configuration");

        // 使用 IniSecurityManagerFactory 提取 shiro.ini 配置文件
        Factory<SecurityManager> factory = new IniSecurityManagerFactory("classpath:shiro.ini");

        // 解析 INI 配置文件并返回该配置文件的 SecurityManager 实例
        SecurityManager securityManager = factory.getInstance();

        // 设置 SecurityManager,和应用程序进行绑定
        // 在Web应用程序中,应该保存至 ServletContext 或 Spring等容器中
        SecurityUtils.setSecurityManager(securityManager);

        // 调用获取当前正在执行的用户, Subject 可以是一个用户,也可以是个第三方进程
        Subject currentUser = SecurityUtils.getSubject();

        // 获取一个用户的会话
        Session session = currentUser.getSession();
        session.setAttribute("someKey", "aValue");
        String value = (String) session.getAttribute("someKey");

        if ("aValue".equals(value)) {
            logger.info("The " + value + " is correct");
        }

        // 如果当前用户的session没有被验证过,需要进行用户信息验证
        if (!currentUser.isAuthenticated()) {
            UsernamePasswordToken token = new UsernamePasswordToken("zhangSan", "aa123");
            // 不需要配置就可以支持 "Remember Me"
            token.setRememberMe(true);

            try {
                // 用户进行登录操作
                currentUser.login(token);
            } catch (UnknownAccountException var1) {
                logger.info("There is no user with username = " + token.getPrincipal());
            } catch (IncorrectCredentialsException var2) {
                logger.info("Password for account " + token.getPrincipal() + " was incorrect");
            } catch (LockedAccountException var3) {
                logger.info("The account for username " + token.getPrincipal() + " is locked." +
                        "Please contact your administrator to unlock it.");
            } catch (AuthenticationException var4) {
                // unexpected condition...error...
            }

            // 获取用户名
            logger.info("User[" + currentUser.getPrincipal() + "] logged in successfully");

            // 用户是否具有某些特定角色
            if (currentUser.hasRole("admin")) {
                logger.info("Welcome, my administrator.");
            } else {
                logger.info("Sorry, you are not an administrator.");
            }

            // 用户是否具有某些权限
            if (currentUser.isPermitted("delete")) {
                logger.info("Yes, you can delete anything.");
            } else {
                logger.info("Sorry, you don't have the delete authority.");
            }

            // 用户注销,移出所有验证信息同时使session无效
            currentUser.logout();
        }
    }
}
